package com.icss.th.fulltext.lucenne;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.icss.th.common.Constants.SEARCH_TYPE;
import com.icss.th.common.config.SystemConfig;
import com.icss.th.db.pojo.PageInfo;
import com.icss.th.fulltext.IFullTextSearch;
import com.icss.th.fulltext.pojo.SearchResult;

public class LucenneFullTextSearch implements IFullTextSearch {
	
	private Analyzer analyzer = null;
	
	public LucenneFullTextSearch(){
		if(this.analyzer == null){
			this.analyzer = new IKAnalyzer(true);
		}
	}

	
	/*
	 * 全文检索-简单查询(non-Javadoc)
	 * @see com.icss.th.fulltext.IFullTextSearch#simpleSearch
	 * subject：检索题库类型
	 * keyword：关键字
	 * pageInfo：分页信息
	 */
	@Override
	public List<SearchResult> simpleSearch(String subject, String keyword, PageInfo pageInfo) {
		Directory dir = null;
		IndexReader reader = null;
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		try {
			dir = FSDirectory.open(new File(SystemConfig.EXAM_INDEX_PATH));
	        reader = DirectoryReader.open(dir);  
	        IndexSearcher searcher = new IndexSearcher(reader); 
	        
	        //=================设置查询条件开始========================
	        BooleanQuery query = new BooleanQuery();
	        Query query1 = null;
	        Query query2 = null;
	        
	        //题库类型query
	        if(!"".equals(subject) && subject != null){
	        	query1 = new TermQuery(new Term("KEYTYPE", subject));
	        	query.add(query1, BooleanClause.Occur.MUST);
	        }
	        
	        //关键字query
	        if(!"".equals(keyword) && keyword != null){
	        	QueryParser parser = new QueryParser(Version.LUCENE_43, "EXAMTITLE", this.analyzer);
		        parser.setDefaultOperator(QueryParser.AND_OPERATOR);
		        query2 = parser.parse(QueryParser.escape(keyword));		//escape解决特殊符号问题
		        query.add(query2, BooleanClause.Occur.MUST);
	        }
	        //=================设置查询条件结束========================
	        
	        
	        TopDocs topdocs = LuceneHandler.search(searcher, query, pageInfo);
	        ScoreDoc[] scoreDocs = topdocs.scoreDocs;  
	        
	        System.out.println("=============lucene共查询出"+topdocs.totalHits+"条结果==================");
	        //用于高亮查询
	        BooleanQuery higherQuery = new BooleanQuery();
	        higherQuery.add(query2, BooleanClause.Occur.MUST);
	        
	        for(int i = 0; i < scoreDocs.length; i++) {
	            Document document = searcher.doc(scoreDocs[i].doc);  
	            SearchResult searchResult = LuceneHandler.settingExamResult(document, higherQuery, this.analyzer);
	            resultList.add(searchResult);
	        }
	        
	        reader.close();  
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return resultList;
	}

	
	/*
	 * 全文检索-高级查询(non-Javadoc)
	 * @see com.icss.th.fulltext.IFullTextSearch#advanceSearch
	 * subject：检索题库类型
	 * pageInfo：分页信息
	 * type：检索内容（题库、试卷）
	 * containKeyword：包含的关键字
	 * notContainKeyword：不包含的关键字
	 * startYear：所属年份开始年
	 * endYear：所属年份结束年
	 */
	@Override
	public List<SearchResult> advanceSearch(String subject, String type,
			String containKeyword, String notContainKeyword, int startYear,
			int endYear, PageInfo pageInfo) {
		Directory dir = null;
		IndexReader reader = null;
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		String path = "";
		String keywordField = "";
		
		try {
			path = SEARCH_TYPE.PAPER.equals(type) ? SystemConfig.PAPER_INDEX_PATH : SystemConfig.EXAM_INDEX_PATH;
			dir = FSDirectory.open(new File(path));
			reader = DirectoryReader.open(dir);  
	        IndexSearcher searcher = new IndexSearcher(reader); 
	        
	        
	        //=================设置查询条件开始========================
	        BooleanQuery query = new BooleanQuery();
	        Query query1 = null;
	        NumericRangeQuery<Integer> query2 = null;
	        Query query3 = null;
	        Query query4 = null;
	        keywordField = SEARCH_TYPE.PAPER.equals(type) ? "PAPERTITLE" : "EXAMTITLE";
	        
	        //题库类型query
	        if(!"".equals(subject) && subject != null){
	        	query1 = new TermQuery(new Term("KEYTYPE", subject));
	        	query.add(query1, BooleanClause.Occur.MUST);
	        }
	        
	        //所属年份query
	        if(startYear > 0 && endYear > 0 && startYear <=endYear){
	        	query2 = NumericRangeQuery.newIntRange("REFERYEAR", startYear, endYear, true, true);
	        	query.add(query2, BooleanClause.Occur.MUST);
	        }
	        
	        //包含的关键字query
	        if(!"".equals(containKeyword) && containKeyword != null){
	        	QueryParser containParser = new QueryParser(Version.LUCENE_43, keywordField, this.analyzer);
		        containParser.setDefaultOperator(QueryParser.AND_OPERATOR);
		        query3 = containParser.parse(QueryParser.escape(containKeyword));		//escape解决特殊符号问题
	        	query.add(query3, BooleanClause.Occur.MUST);
	        }
	        
	        //不包含的关键字query
	        if(!"".equals(notContainKeyword) && notContainKeyword != null){
	        	QueryParser notContainParser = new QueryParser(Version.LUCENE_43, keywordField, this.analyzer);
		        notContainParser.setDefaultOperator(QueryParser.AND_OPERATOR);
		        query4 = notContainParser.parse(QueryParser.escape(notContainKeyword));
	        	query.add(query4, BooleanClause.Occur.MUST_NOT);
	        }
	        //=================设置查询条件结束========================
	        
	        TopDocs topdocs = LuceneHandler.search(searcher, query, pageInfo);
	        
	        if (topdocs != null)
	        {
		        ScoreDoc[] scoreDocs = topdocs.scoreDocs;  
		        
		        System.out.println("=============lucene共查询出"+topdocs.totalHits+"条结果==================");
		        //用于高亮查询
		        BooleanQuery higherQuery = new BooleanQuery();
		        higherQuery.add(query3, BooleanClause.Occur.MUST);
		        
		        for(int i = 0; i < scoreDocs.length; i++) {
		            Document document = searcher.doc(scoreDocs[i].doc);  
		            SearchResult searchResult = new SearchResult();
		            if(SEARCH_TYPE.PAPER.equals(type)){
		            	searchResult = LuceneHandler.settingPaperResult(document, higherQuery, this.analyzer);
		            }else{
		            	searchResult = LuceneHandler.settingExamResult(document, higherQuery, this.analyzer);
		            }
		            resultList.add(searchResult);
		        }
	        }
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} finally{
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
        
		return resultList;
	}


	/**
	 * 获取卷子中的题目
	 * @param paperId
	 * @return
	 */
	@Override
	public List<SearchResult> getExamByPaperId(String paperId, PageInfo pageInfo) {
		Directory dir = null;
		IndexReader reader = null;
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		try {
			dir = FSDirectory.open(new File(SystemConfig.EXAM_INDEX_PATH));
	        reader = DirectoryReader.open(dir);  
	        IndexSearcher searcher = new IndexSearcher(reader); 
	        
	        //=================设置查询条件开始========================
	        BooleanQuery query = new BooleanQuery();
	        Query query1 = null;
	        
	        //卷子IDquery
	        if(!"".equals(paperId) && paperId != null){
	        	query1 = new TermQuery(new Term("INPAPERID", paperId));
	        	query.add(query1, BooleanClause.Occur.MUST);
	        }
	        
	        //=================设置查询条件结束========================
	        
	        TopDocs topdocs = LuceneHandler.search(searcher, query, pageInfo);
	        ScoreDoc[] scoreDocs = topdocs.scoreDocs;  
	        
	        System.out.println("=============lucene共查询出"+topdocs.totalHits+"条结果==================");
	        
	        for(int i = 0; i < scoreDocs.length; i++) {
	            Document document = searcher.doc(scoreDocs[i].doc);  
	            SearchResult searchResult = LuceneHandler.settingExamResult(document, null, this.analyzer);
	            resultList.add(searchResult);
	        }
	        
	        reader.close();  
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(reader != null){
				try {
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return resultList;
	}

}
